﻿// 
// SoapTrace.Net - A soap message monitoring utility. 
// 
// Copyright (C) 2004 Matthew Ward
// 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
// 
// Matthew Ward (mrward@users.sourceforge.net)
// 

using NUnit.Framework;
using SoapTrace.Core.Communication;
using System;
using System.Text;

namespace SoapTrace.Tests
{
	/// <summary>
	/// Test fixture to test the parsing of a "chunked" soap response.
	/// </summary>
	/// <remarks><para>A chunked http message does not have a message size in the http 
	/// header, but instead the message body contains a series of chunks.  Each chunk
	/// contains two parts, the size in bytes of the chunk and the chunk's bytes. </para>
	/// 
	/// <para>From the Http 1.1 RFC:</para>
	/// <para>
	/// <code>
	///        Chunked-Body   = *chunk
	///	                        last-chunk
	///	                        trailer
	///	                        CRLF
	///
	///	       chunk          = chunk-size [ chunk-extension ] CRLF
	///	                        chunk-data CRLF
	///	                        chunk-size     = 1*HEX
	///																					
	///	       last-chunk     = 1*("0") [ chunk-extension ] CRLF
	/// </code>
	/// </para>
	/// <para>The current <see cref="SoapTrace.Core.Communication.SoapResponse"/>
	/// class does not handle chunk extensions.</para>
	/// </remarks>
	[ TestFixture ]
	public class ChunkedHttpResponseSingleChunkTextFixture
	{
		/// <summary>
		/// The complete Http message including the chunked body.
		/// </summary>
		private string m_HttpResponseMessage = String.Empty;

		/// <summary>
		/// The Http header that will be parsed.
		/// </summary>
		private string m_HttpHeader = "HTTP/1.1 200 OK\r\nServer: Microsoft-IIS/5.0\r\nDate: Sun, 04 Jul 2004 10:10:51 GMT\r\nX-Powered-By: ASP.NET\r\nX-AspNet-Version: 1.1.4322\r\nTransfer-Encoding: chunked\r\nCache-Control: private, max-age=0\r\nContent-Type: text/xml; charset=utf-8\r\n\r\n";																																																																					   
		
		/// <summary>
		/// The expected message that will be extracted from the Http message body.
		/// </summary>
		private string m_HttpMessageBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><AddResponse xmlns=\"http://tempuri.org/\"><AddResult>11</AddResult></AddResponse></soap:Body></soap:Envelope>";
		
		/// <summary>
		/// The Http message body containg the chunked data.
		/// </summary>
		private string m_ChunkedHttpMessageBody = String.Empty;

		/// <summary>
		/// The soap response under test.
		/// </summary>
		private SoapResponse m_Response = new SoapResponse( );

		/// <summary>
		/// Initialises each test.  Sets up a Http message that contains a single
		/// chunk.
		/// </summary>
		[ SetUp ]
		public void Init( )
		{
			// Create chunked http message body.
			m_ChunkedHttpMessageBody = String.Concat( "146\r\n", m_HttpMessageBody, "\r\n0\r\n\r\n" );

			// Create the complete http message.
			m_HttpResponseMessage = String.Concat( m_HttpHeader, m_ChunkedHttpMessageBody );

			// Convert the message to bytes.
			byte[ ] Bytes = UnicodeEncoding.UTF8.GetBytes( m_HttpResponseMessage );

			// Parse the http message.

			for( int i = 0; i < Bytes.Length; ++i )
			{
				byte MessageByte = Bytes[ i ];

				bool EndOfMessage = m_Response.AddByte( MessageByte );

				if( Bytes.Length == ( i + 1 ) )
				{
					Assert.IsTrue( EndOfMessage, "Should be at the end of the message." );
				}
				else
				{
					Assert.IsFalse( EndOfMessage, "Should not be at the end of the message." );
				}
			}
		}

		/// <summary>
		/// Tests that a "chunked" soap response with a single chunk is correctly 
		/// parsed.
		/// </summary>
		[ Test ]
		public void MessageReceived( )
		{
			Assert.AreEqual( m_HttpHeader, m_Response.Header, "Soap Header is wrong." );
			Assert.AreEqual( m_HttpMessageBody, m_Response.Message, "Soap Message is wrong." );
		}
	}
}
